home *** CD-ROM | disk | FTP | other *** search
/ Shareware Extravaganza 7 / Shareware Extravaganza 8 (Most Significant Bits) (Disc 7).iso / win95b / readfile.zip / CRC.CPP next >
C/C++ Source or Header  |  1996-05-05  |  5KB  |  150 lines

  1. // --------------------------------------------------------------------------
  2. //  PROJECT     SOLO2
  3. //  MODULE      CRC.C           
  4. //  PURPOSE     32 bit CRC routines
  5. //  COPYRIGHT   (c) Francois Liger, 1994
  6. // --------------------------------------------------------------------------
  7. //  COMMENTS    CRC 32 implementation complies with 
  8. // --------------------------------------------------------------------------
  9.  
  10. #include <windows.h>
  11. #include "crc.h"
  12.  
  13. // --------------------------------------------------------------------------
  14. //  module wide definitions
  15. // --------------------------------------------------------------------------
  16.  
  17. #define CRC_POLYNOMIAL  0xEDB88320L     // standard polynomial constant
  18.  
  19. DWORD dwCRCTable[256];                  // CRC table (1 KB)
  20.  
  21. // --------------------------------------------------------------------------
  22. //  FUNCTION    InitializeCRCTable
  23. //  PURPOSE     initializes CRC table with proper values
  24. // --------------------------------------------------------------------------
  25. //  INPUT       void
  26. //
  27. //  OUTPUT      void
  28. // --------------------------------------------------------------------------
  29. //  COMMENTS    
  30. // --------------------------------------------------------------------------
  31.  
  32. void InitializeCRCTable(void)
  33. {
  34.   int   i, j;
  35.   DWORD dwCRC;
  36.  
  37.   for(i = 0; i < 256; i++)
  38.   {
  39.     dwCRC = i;
  40.     for(j = 8; j > 0; j--)
  41.     {
  42.       if(dwCRC & 1)
  43.     dwCRC = (dwCRC >> 1) ^ CRC_POLYNOMIAL; 
  44.       else  
  45.     dwCRC >>= 1;
  46.     }
  47.     dwCRCTable[i] = dwCRC;
  48.   }
  49. }
  50.  
  51. // --------------------------------------------------------------------------
  52. //  FUNCTION    ComputeBufferCRC
  53. //  PURPOSE     compute buffer CRC
  54. // --------------------------------------------------------------------------
  55. //  INPUT       dwCRC           CRC initial value
  56. //              pvBuffer        pointer to buffer to compute CRC for
  57. //              cbBuffer        size of buffer in bytes
  58. //
  59. //  OUTPUT      DWORD           CRC value
  60. // --------------------------------------------------------------------------
  61. //  COMMENTS    this function computes the CRC for a block of data.
  62. //              it accepts a CRC initial value and returns the updated value.
  63. //              uses dwCRCTable array.
  64. // --------------------------------------------------------------------------
  65. #pragma optimize("agt",on)
  66. DWORD ComputeBufferCRC(DWORD dwCRC, void *pvBuffer, DWORD cbBuffer)
  67. {
  68.   PBYTE pb;
  69.   DWORD dwTmp1, dwTmp2;
  70.   UINT  i;
  71.  
  72.   pb = (PBYTE)pvBuffer;
  73.   /*
  74.   for(i = 0; i < cbBuffer; i++)
  75.   {
  76.     dwTmp1 = (dwCRC >> 8) & 0x00FFFFFFL;
  77.     dwTmp2 = dwCRCTable[((int)dwCRC ^ *pb++) & 0xFF];
  78.     dwCRC  = dwTmp1 ^ dwTmp2;
  79.   }    */
  80.   {
  81.   DWORD dwFour,dwRest;
  82.   dwFour = cbBuffer/8;
  83.   dwRest = cbBuffer - (dwFour*8);
  84.  
  85.     for(i = 0; i < dwFour ; i++)
  86.     {
  87.             
  88.       dwCRC  = (dwCRC >> 8) ^ (dwCRCTable[(BYTE)(((BYTE)dwCRC ^ *pb))]);
  89.       dwCRC  = (dwCRC >> 8) ^ (dwCRCTable[(BYTE)(((BYTE)dwCRC ^ *(pb+1)))]);
  90.       dwCRC  = (dwCRC >> 8) ^ (dwCRCTable[(BYTE)(((BYTE)dwCRC ^ *(pb+2)))]);
  91.       dwCRC  = (dwCRC >> 8) ^ (dwCRCTable[(BYTE)(((BYTE)dwCRC ^ *(pb+3)))]);
  92.       
  93.       dwCRC  = (dwCRC >> 8) ^ (dwCRCTable[(BYTE)(((BYTE)dwCRC ^ *(pb+4)))]);
  94.       dwCRC  = (dwCRC >> 8) ^ (dwCRCTable[(BYTE)(((BYTE)dwCRC ^ *(pb+5)))]);
  95.       dwCRC  = (dwCRC >> 8) ^ (dwCRCTable[(BYTE)(((BYTE)dwCRC ^ *(pb+6)))]);
  96.       dwCRC  = (dwCRC >> 8) ^ (dwCRCTable[(BYTE)(((BYTE)dwCRC ^ *(pb+7)))]);
  97.  
  98.       pb+=8;
  99.  
  100.     }    
  101.  
  102.     for(i = 0; i < dwRest; i++)
  103.     {
  104.       dwTmp1 = (dwCRC >> 8) & 0x00FFFFFFL;
  105.       dwTmp2 = dwCRCTable[((int)dwCRC ^ *pb++) & 0xFF];
  106.       dwCRC  = dwTmp1 ^ dwTmp2;
  107.     }    
  108.  
  109.   }
  110.   return dwCRC;
  111. }
  112.  
  113. // --------------------------------------------------------------------------
  114. //  FUNCTION    ComputeFileCRC
  115. //  PURPOSE     compute file CRC
  116. // --------------------------------------------------------------------------
  117. //  INPUT       hf              file handle
  118. //              lpOverlapped    pointer to OVERLAPPED info for async. I/O 
  119. //
  120. //  OUTPUT      DWORD           CRC value
  121. // --------------------------------------------------------------------------
  122. //  COMMENTS    this function computes the CRC for a file. The CRC value is
  123. //              set with all 1's and then every it is inverted once the file
  124. //              hqs been done. This gives a CRC value that corresponds with
  125. //              the values calculated by PKZIP, ARJ...
  126. // --------------------------------------------------------------------------
  127.  
  128. DWORD ComputeFileCRC(HANDLE hfile, LPOVERLAPPED lpOverlapped)
  129. {
  130.   DWORD dwCRC;
  131.   BYTE  bBuffer[CRC_BUFFER_SIZE];
  132.   DWORD cbBuffer;
  133.  
  134.   // set CRC with 1's
  135.   dwCRC = 0xFFFFFFFFL;
  136.  
  137.   // read file and compute CRC
  138.   for(;;)
  139.   {
  140.     ReadFile(hfile, &bBuffer, CRC_BUFFER_SIZE, &cbBuffer, lpOverlapped);
  141.     if(cbBuffer == 0)
  142.       break;
  143.  
  144.     dwCRC = ComputeBufferCRC(dwCRC, &bBuffer, cbBuffer);
  145.   }
  146.   
  147.   // invert CRC
  148.   return(dwCRC ^= 0xFFFFFFFFL);
  149. }
  150.